﻿namespace HutongGames.PlayMaker
{
    using HutongGames.PlayMaker.Actions;
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using UnityEngine;

    [Serializable]
    public class ActionData
    {
        [SerializeField]
        private List<bool> actionEnabled = new List<bool>();
        public static readonly Dictionary<System.Type, FieldInfo[]> ActionFieldsLookup = new Dictionary<System.Type, FieldInfo[]>();
        [SerializeField]
        private List<int> actionHashCodes = new List<int>();
        [SerializeField]
        private List<bool> actionIsOpen = new List<bool>();
        [SerializeField]
        private List<string> actionNames = new List<string>();
        [SerializeField]
        private List<int> actionStartIndex = new List<int>();
        private static readonly Dictionary<string, System.Type> ActionTypeLookup = new Dictionary<string, System.Type>();
        [SerializeField]
        private List<FsmAnimationCurve> animationCurveParams = new List<FsmAnimationCurve>();
        [SerializeField]
        private List<int> arrayParamSizes = new List<int>();
        [SerializeField]
        private List<string> arrayParamTypes = new List<string>();
        private static List<string> assemblies;
        [SerializeField]
        private List<byte> byteData = new List<byte>();
        private byte[] byteDataAsArray;
        private static FsmStateAction currentAction;
        private static int currentActionIndex;
        private static Fsm currentFsm;
        private static FsmState currentState;
        [SerializeField]
        private List<string> customNames = new List<string>();
        [SerializeField]
        private List<FsmEventTarget> fsmEventTargetParams = new List<FsmEventTarget>();
        [SerializeField]
        private List<FsmGameObject> fsmGameObjectParams = new List<FsmGameObject>();
        [SerializeField]
        private List<FsmObject> fsmObjectParams = new List<FsmObject>();
        [SerializeField]
        private List<FsmOwnerDefault> fsmOwnerDefaultParams = new List<FsmOwnerDefault>();
        [SerializeField]
        private List<FsmProperty> fsmPropertyParams = new List<FsmProperty>();
        [SerializeField]
        private List<FsmString> fsmStringParams = new List<FsmString>();
        [SerializeField]
        private List<FunctionCall> functionCallParams = new List<FunctionCall>();
        private static readonly List<FieldInfo> InitFields = new List<FieldInfo>();
        [SerializeField]
        private List<LayoutOption> layoutOptionParams = new List<LayoutOption>();
        private int nextParamIndex;
        [SerializeField]
        private List<int> paramByteDataSize = new List<int>();
        [SerializeField]
        private List<int> paramDataPos = new List<int>();
        [SerializeField]
        private List<ParamDataType> paramDataType = new List<ParamDataType>();
        [SerializeField]
        private List<string> paramName = new List<string>();
        private static bool resaveActionData;
        [SerializeField]
        private List<UnityEngine.Object> unityObjectParams = new List<UnityEngine.Object>();
        private static readonly List<int> UsedIndices = new List<int>();

        private void AddByteData(ICollection<byte> bytes)
        {
            this.paramDataPos.Add(this.byteData.Count);
            if (bytes != null)
            {
                this.paramByteDataSize.Add(bytes.Count);
                this.byteData.AddRange(bytes);
            }
            else
            {
                this.paramByteDataSize.Add(0);
            }
        }

        private void ClearActionData()
        {
            this.actionNames.Clear();
            this.customNames.Clear();
            this.actionEnabled.Clear();
            this.actionIsOpen.Clear();
            this.actionStartIndex.Clear();
            this.actionHashCodes.Clear();
            this.unityObjectParams.Clear();
            this.fsmStringParams.Clear();
            this.fsmObjectParams.Clear();
            this.fsmGameObjectParams.Clear();
            this.fsmOwnerDefaultParams.Clear();
            this.animationCurveParams.Clear();
            this.functionCallParams.Clear();
            this.fsmPropertyParams.Clear();
            this.fsmEventTargetParams.Clear();
            this.layoutOptionParams.Clear();
            this.byteData.Clear();
            this.paramDataPos.Clear();
            this.paramByteDataSize.Clear();
            this.arrayParamSizes.Clear();
            this.arrayParamTypes.Clear();
            this.paramDataType.Clear();
            this.paramName.Clear();
            this.nextParamIndex = 0;
        }

        private object ConvertType(ParamDataType originalParamType, ParamDataType currentParamType, int paramIndex)
        {
            if ((originalParamType == ParamDataType.String) && (currentParamType == ParamDataType.FsmString))
            {
                FsmString str = new FsmString();
                str.Value = FsmUtility.ByteArrayToString(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
                return str;
            }
            if ((originalParamType == ParamDataType.Integer) && (currentParamType == ParamDataType.FsmInt))
            {
                FsmInt num = new FsmInt();
                num.Value = FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return num;
            }
            if ((originalParamType == ParamDataType.Float) && (currentParamType == ParamDataType.FsmFloat))
            {
                FsmFloat num2 = new FsmFloat();
                num2.Value = FsmUtility.BitConverter.ToSingle(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return num2;
            }
            if ((originalParamType == ParamDataType.Boolean) && (currentParamType == ParamDataType.FsmBool))
            {
                FsmBool @bool = new FsmBool();
                @bool.Value = FsmUtility.BitConverter.ToBoolean(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return @bool;
            }
            if ((originalParamType == ParamDataType.GameObject) && (currentParamType == ParamDataType.FsmGameObject))
            {
                FsmGameObject obj2 = new FsmGameObject();
                obj2.Value = (GameObject) this.unityObjectParams[this.paramDataPos[paramIndex]];
                return obj2;
            }
            if ((originalParamType == ParamDataType.GameObject) && (currentParamType == ParamDataType.FsmOwnerDefault))
            {
                FsmOwnerDefault default3 = new FsmOwnerDefault();
                FsmGameObject obj3 = new FsmGameObject();
                obj3.Value = (GameObject) this.unityObjectParams[this.paramDataPos[paramIndex]];
                default3.GameObject = obj3;
                default3.OwnerOption = OwnerDefaultOption.SpecifyGameObject;
                return default3;
            }
            if ((originalParamType == ParamDataType.FsmGameObject) && (currentParamType == ParamDataType.FsmOwnerDefault))
            {
                FsmOwnerDefault default5 = new FsmOwnerDefault();
                default5.GameObject = this.fsmGameObjectParams[this.paramDataPos[paramIndex]];
                default5.OwnerOption = OwnerDefaultOption.SpecifyGameObject;
                return default5;
            }
            if ((originalParamType == ParamDataType.Vector3) && (currentParamType == ParamDataType.FsmVector3))
            {
                FsmVector3 vector = new FsmVector3();
                vector.Value = FsmUtility.ByteArrayToVector3(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return vector;
            }
            if ((originalParamType == ParamDataType.Rect) && (currentParamType == ParamDataType.FsmRect))
            {
                FsmRect rect = new FsmRect();
                rect.Value = FsmUtility.ByteArrayToRect(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return rect;
            }
            if ((originalParamType == ParamDataType.Quaternion) && (currentParamType == ParamDataType.Quaternion))
            {
                FsmQuaternion quaternion = new FsmQuaternion();
                quaternion.Value = FsmUtility.ByteArrayToQuaternion(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return quaternion;
            }
            if ((originalParamType == ParamDataType.Color) && (currentParamType == ParamDataType.FsmColor))
            {
                FsmColor color = new FsmColor();
                color.Value = FsmUtility.ByteArrayToColor(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                return color;
            }
            if ((currentParamType == ParamDataType.FsmMaterial) && (originalParamType == ParamDataType.ObjectReference))
            {
                FsmMaterial material = new FsmMaterial();
                material.Value = this.unityObjectParams[this.paramDataPos[paramIndex]] as Material;
                return material;
            }
            if ((currentParamType == ParamDataType.FsmTexture) && (originalParamType == ParamDataType.ObjectReference))
            {
                FsmTexture texture = new FsmTexture();
                texture.Value = this.unityObjectParams[this.paramDataPos[paramIndex]] as Texture;
                return texture;
            }
            if ((currentParamType == ParamDataType.FsmObject) && (originalParamType == ParamDataType.ObjectReference))
            {
                FsmObject obj4 = new FsmObject();
                obj4.Value = this.unityObjectParams[this.paramDataPos[paramIndex]];
                return obj4;
            }
            return null;
        }

        public ActionData Copy()
        {
            ActionData data2 = new ActionData();
            data2.actionNames = new List<string>(this.actionNames);
            data2.customNames = new List<string>(this.customNames);
            data2.actionEnabled = new List<bool>(this.actionEnabled);
            data2.actionIsOpen = new List<bool>(this.actionIsOpen);
            data2.actionStartIndex = new List<int>(this.actionStartIndex);
            data2.actionHashCodes = new List<int>(this.actionHashCodes);
            data2.unityObjectParams = new List<UnityEngine.Object>(this.unityObjectParams);
            data2.fsmStringParams = this.CopyFsmStringParams();
            data2.fsmObjectParams = this.CopyFsmObjectParams();
            data2.fsmGameObjectParams = this.CopyFsmGameObjectParams();
            data2.fsmOwnerDefaultParams = this.CopyFsmOwnerDefaultParams();
            data2.animationCurveParams = this.CopyAnimationCurveParams();
            data2.functionCallParams = this.CopyFunctionCallParams();
            data2.fsmPropertyParams = this.CopyFsmPropertyParams();
            data2.fsmEventTargetParams = this.CopyFsmEventTargetParams();
            data2.layoutOptionParams = this.CopyLayoutOptionParams();
            data2.byteData = new List<byte>(this.byteData);
            data2.paramDataPos = new List<int>(this.paramDataPos);
            data2.paramByteDataSize = new List<int>(this.paramByteDataSize);
            data2.paramDataType = new List<ParamDataType>(this.paramDataType);
            data2.arrayParamSizes = new List<int>(this.arrayParamSizes);
            data2.arrayParamTypes = new List<string>(this.arrayParamTypes);
            data2.paramName = new List<string>(this.paramName);
            return data2;
        }

        private List<FsmAnimationCurve> CopyAnimationCurveParams()
        {
            List<FsmAnimationCurve> list = new List<FsmAnimationCurve>();
            foreach (FsmAnimationCurve curve in this.animationCurveParams)
            {
                FsmAnimationCurve curve3 = new FsmAnimationCurve();
                curve3.curve.keys = curve.curve.keys;
                FsmAnimationCurve item = curve3;
                list.Add(item);
            }
            return list;
        }

        private List<FsmEventTarget> CopyFsmEventTargetParams()
        {
            List<FsmEventTarget> list = new List<FsmEventTarget>();
            foreach (FsmEventTarget target in this.fsmEventTargetParams)
            {
                list.Add(new FsmEventTarget(target));
            }
            return list;
        }

        private List<FsmGameObject> CopyFsmGameObjectParams()
        {
            List<FsmGameObject> list = new List<FsmGameObject>();
            foreach (FsmGameObject obj2 in this.fsmGameObjectParams)
            {
                list.Add(new FsmGameObject(obj2));
            }
            return list;
        }

        private List<FsmObject> CopyFsmObjectParams()
        {
            List<FsmObject> list = new List<FsmObject>();
            foreach (FsmObject obj2 in this.fsmObjectParams)
            {
                list.Add(new FsmObject(obj2));
            }
            return list;
        }

        private List<FsmOwnerDefault> CopyFsmOwnerDefaultParams()
        {
            List<FsmOwnerDefault> list = new List<FsmOwnerDefault>();
            foreach (FsmOwnerDefault default2 in this.fsmOwnerDefaultParams)
            {
                list.Add(new FsmOwnerDefault(default2));
            }
            return list;
        }

        private List<FsmProperty> CopyFsmPropertyParams()
        {
            List<FsmProperty> list = new List<FsmProperty>();
            foreach (FsmProperty property in this.fsmPropertyParams)
            {
                list.Add(new FsmProperty(property));
            }
            return list;
        }

        private List<FsmString> CopyFsmStringParams()
        {
            List<FsmString> list = new List<FsmString>();
            foreach (FsmString str in this.fsmStringParams)
            {
                list.Add(new FsmString(str));
            }
            return list;
        }

        private List<FunctionCall> CopyFunctionCallParams()
        {
            List<FunctionCall> list = new List<FunctionCall>();
            foreach (FunctionCall call in this.functionCallParams)
            {
                list.Add(new FunctionCall(call));
            }
            return list;
        }

        private List<LayoutOption> CopyLayoutOptionParams()
        {
            List<LayoutOption> list = new List<LayoutOption>();
            foreach (LayoutOption option in this.layoutOptionParams)
            {
                list.Add(new LayoutOption(option));
            }
            return list;
        }

        public FsmStateAction CreateAction(FsmState state, int actionIndex)
        {
            currentFsm = state.Fsm;
            currentState = state;
            currentActionIndex = actionIndex;
            FsmUtility.CurrentFsm = state.Fsm;
            if (state.Fsm == null)
            {
                Debug.LogError("state.Fsm == null");
            }
            string actionName = this.actionNames[actionIndex];
            System.Type actionType = GetActionType(actionName);
            if (actionType == null)
            {
                string str2 = TryFixActionName(actionName);
                actionType = GetActionType(str2);
                if (actionType == null)
                {
                    MissingAction action = (MissingAction) Activator.CreateInstance(typeof(MissingAction));
                    string str3 = FsmUtility.StripNamespace(actionName);
                    action.actionName = str3;
                    currentAction = action;
                    LogError("Could Not Create Action: " + str3 + " (Maybe the script was removed?)");
                    Debug.LogError("Could Not Create Action: " + FsmUtility.GetPath(state) + str3 + " (Maybe the script was removed?)");
                    resaveActionData = true;
                    return currentAction;
                }
                string str4 = "Action : " + actionName + " Updated To: " + str2;
                LogInfo(str4);
                Debug.Log(str4);
                actionName = str2;
                resaveActionData = true;
            }
            FsmStateAction action2 = (FsmStateAction) Activator.CreateInstance(actionType);
            currentAction = action2;
            action2.Reset();
            if (Application.isEditor)
            {
                if ((this.paramDataType.Count != this.paramDataPos.Count) || (this.paramName.Count != this.paramDataPos.Count))
                {
                    Debug.LogWarning("Old data format detected! Updating...");
                    resaveActionData = true;
                }
                int num = this.actionHashCodes[actionIndex];
                if (num != GetActionTypeHashCode(actionType))
                {
                    resaveActionData = true;
                    if (this.paramDataType.Count != this.paramDataPos.Count)
                    {
                        LogError("Action has changed since FSM was saved. Could not recover parameters. Parameters reset to default values.");
                        Debug.LogError("Action script has changed since Fsm was saved: " + FsmUtility.GetPath(state) + FsmUtility.StripNamespace(actionName) + ". Parameters reset to default values...");
                        return action2;
                    }
                    try
                    {
                        action2 = this.TryRecoverAction(actionType, action2, actionIndex);
                    }
                    catch
                    {
                        LogError("Action has changed since FSM was saved. Could not recover parameters. Parameters reset to default values.");
                    }
                    return action2;
                }
            }
            this.nextParamIndex = this.actionStartIndex[actionIndex];
            foreach (FieldInfo info in GetFields(actionType))
            {
                try
                {
                    this.LoadActionField(action2, info, this.nextParamIndex);
                }
                catch (Exception)
                {
                    Debug.LogError("Error loading action: " + FsmState.GetFullStateLabel(state) + " : " + actionName + " : " + info.Name);
                }
                this.nextParamIndex++;
            }
            if (this.customNames.Count > actionIndex)
            {
                action2.Name = this.customNames[actionIndex];
            }
            if (this.actionEnabled.Count > actionIndex)
            {
                action2.Enabled = this.actionEnabled[actionIndex];
            }
            action2.IsOpen = (this.actionIsOpen.Count <= actionIndex) ? true : this.actionIsOpen[actionIndex];
            return action2;
        }

        private FieldInfo FindField(System.Type actionType, int paramIndex)
        {
            string str = this.paramName[paramIndex];
            ParamDataType type = this.paramDataType[paramIndex];
            foreach (FieldInfo info in GetFields(actionType))
            {
                ParamDataType paramDataType = GetParamDataType(info.FieldType);
                if (((info.Name == str) && (paramDataType == type)) && !InitFields.Contains(info))
                {
                    if (paramDataType == ParamDataType.Array)
                    {
                        System.Type elementType = info.GetType().GetElementType();
                        if (elementType == null)
                        {
                            return null;
                        }
                        if (this.arrayParamTypes[paramIndex] == elementType.FullName)
                        {
                            return info;
                        }
                    }
                    return info;
                }
            }
            return null;
        }

        private static FieldInfo FindField(System.Type actionType, string name)
        {
            foreach (FieldInfo info in GetFields(actionType))
            {
                if ((info.Name == name) && !InitFields.Contains(info))
                {
                    return info;
                }
            }
            return null;
        }

        private static System.Type GetActionType(string actionName)
        {
            System.Type globalType;
            if (!ActionTypeLookup.TryGetValue(actionName, out globalType))
            {
                globalType = GetGlobalType(actionName);
                if (globalType == null)
                {
                    return null;
                }
                ActionTypeLookup.Add(actionName, globalType);
            }
            return globalType;
        }

        private static int GetActionTypeHashCode(System.Type actionType)
        {
            string str = "";
            foreach (FieldInfo info in GetFields(actionType))
            {
                str = str + info.FieldType.ToString();
            }
            return str.GetHashCode();
        }

        public static FieldInfo[] GetFields(System.Type actionType)
        {
            FieldInfo[] fields;
            if (!ActionFieldsLookup.TryGetValue(actionType, out fields))
            {
                fields = actionType.GetFields(BindingFlags.Public | BindingFlags.Instance);
                ActionFieldsLookup.Add(actionType, fields);
            }
            return fields;
        }

        private FsmEventTarget GetFsmEventTarget(int paramIndex)
        {
            FsmEventTarget target = this.fsmEventTargetParams[this.paramDataPos[paramIndex]];
            if (target == null)
            {
                return new FsmEventTarget();
            }
            if (!string.IsNullOrEmpty(target.excludeSelf.Name))
            {
                target.excludeSelf = currentFsm.GetFsmBool(target.excludeSelf.Name);
            }
            string name = target.gameObject.GameObject.Name;
            if (!string.IsNullOrEmpty(name))
            {
                target.gameObject.GameObject = currentFsm.GetFsmGameObject(name);
            }
            if (!string.IsNullOrEmpty(target.fsmName.Name))
            {
                target.fsmName = currentFsm.GetFsmString(target.fsmName.Name);
            }
            if (!string.IsNullOrEmpty(target.sendToChildren.Name))
            {
                target.sendToChildren = currentFsm.GetFsmBool(target.sendToChildren.Name);
            }
            return target;
        }

        private FsmGameObject GetFsmGameObject(int paramIndex)
        {
            FsmGameObject obj2 = this.fsmGameObjectParams[this.paramDataPos[paramIndex]];
            if (obj2 == null)
            {
                return new FsmGameObject();
            }
            if (string.IsNullOrEmpty(obj2.Name))
            {
                return obj2;
            }
            return currentFsm.GetFsmGameObject(obj2.Name);
        }

        private FsmMaterial GetFsmMaterial(int paramIndex)
        {
            FsmObject source = this.fsmObjectParams[this.paramDataPos[paramIndex]];
            if (source == null)
            {
                return new FsmMaterial();
            }
            if (string.IsNullOrEmpty(source.Name))
            {
                return new FsmMaterial(source);
            }
            return currentFsm.GetFsmMaterial(source.Name);
        }

        private FsmObject GetFsmObject(int paramIndex)
        {
            FsmObject obj2 = this.fsmObjectParams[this.paramDataPos[paramIndex]];
            if (obj2 == null)
            {
                return new FsmObject();
            }
            if (string.IsNullOrEmpty(obj2.Name))
            {
                return obj2;
            }
            return currentFsm.GetFsmObject(obj2.Name);
        }

        private FsmOwnerDefault GetFsmOwnerDefault(int paramIndex)
        {
            FsmOwnerDefault default2 = this.fsmOwnerDefaultParams[this.paramDataPos[paramIndex]];
            if (default2 == null)
            {
                return new FsmOwnerDefault();
            }
            string name = default2.GameObject.Name;
            if (!string.IsNullOrEmpty(name))
            {
                default2.GameObject = currentFsm.GetFsmGameObject(name);
            }
            return default2;
        }

        private FsmProperty GetFsmProperty(int paramIndex)
        {
            FsmProperty property = this.fsmPropertyParams[this.paramDataPos[paramIndex]];
            if (property == null)
            {
                return new FsmProperty();
            }
            if (!string.IsNullOrEmpty(property.TargetObject.Name))
            {
                property.TargetObject = currentFsm.GetFsmObject(property.TargetObject.Name);
            }
            if (!string.IsNullOrEmpty(property.BoolParameter.Name))
            {
                property.BoolParameter = currentFsm.GetFsmBool(property.BoolParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.FloatParameter.Name))
            {
                property.FloatParameter = currentFsm.GetFsmFloat(property.FloatParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.GameObjectParameter.Name))
            {
                property.GameObjectParameter = currentFsm.GetFsmGameObject(property.GameObjectParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.IntParameter.Name))
            {
                property.IntParameter = currentFsm.GetFsmInt(property.IntParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.MaterialParameter.Name))
            {
                property.MaterialParameter = currentFsm.GetFsmMaterial(property.MaterialParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.ObjectParameter.Name))
            {
                property.ObjectParameter = currentFsm.GetFsmObject(property.ObjectParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.QuaternionParameter.Name))
            {
                property.QuaternionParameter = currentFsm.GetFsmQuaternion(property.QuaternionParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.RectParamater.Name))
            {
                property.RectParamater = currentFsm.GetFsmRect(property.RectParamater.Name);
            }
            if (!string.IsNullOrEmpty(property.StringParameter.Name))
            {
                property.StringParameter = currentFsm.GetFsmString(property.StringParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.TextureParameter.Name))
            {
                property.TextureParameter = currentFsm.GetFsmTexture(property.TextureParameter.Name);
            }
            if (!string.IsNullOrEmpty(property.Vector3Parameter.Name))
            {
                property.Vector3Parameter = currentFsm.GetFsmVector3(property.Vector3Parameter.Name);
            }
            return property;
        }

        private FsmString GetFsmString(int paramIndex)
        {
            FsmString str = this.fsmStringParams[this.paramDataPos[paramIndex]];
            if (str == null)
            {
                return new FsmString();
            }
            if (string.IsNullOrEmpty(str.Name))
            {
                return str;
            }
            return currentFsm.GetFsmString(str.Name);
        }

        private FsmTexture GetFsmTexture(int paramIndex)
        {
            FsmObject source = this.fsmObjectParams[this.paramDataPos[paramIndex]];
            if (source == null)
            {
                return new FsmTexture();
            }
            if (string.IsNullOrEmpty(source.Name))
            {
                return new FsmTexture(source);
            }
            return currentFsm.GetFsmTexture(source.Name);
        }

        private FunctionCall GetFunctionCall(int paramIndex)
        {
            FunctionCall call = this.functionCallParams[this.paramDataPos[paramIndex]];
            if (call == null)
            {
                return new FunctionCall();
            }
            if (!string.IsNullOrEmpty(call.BoolParameter.Name))
            {
                call.BoolParameter = currentFsm.GetFsmBool(call.BoolParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.FloatParameter.Name))
            {
                call.FloatParameter = currentFsm.GetFsmFloat(call.FloatParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.GameObjectParameter.Name))
            {
                call.GameObjectParameter = currentFsm.GetFsmGameObject(call.GameObjectParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.IntParameter.Name))
            {
                call.IntParameter = currentFsm.GetFsmInt(call.IntParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.MaterialParameter.Name))
            {
                call.MaterialParameter = currentFsm.GetFsmMaterial(call.MaterialParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.ObjectParameter.Name))
            {
                call.ObjectParameter = currentFsm.GetFsmObject(call.ObjectParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.QuaternionParameter.Name))
            {
                call.QuaternionParameter = currentFsm.GetFsmQuaternion(call.QuaternionParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.RectParamater.Name))
            {
                call.RectParamater = currentFsm.GetFsmRect(call.RectParamater.Name);
            }
            if (!string.IsNullOrEmpty(call.StringParameter.Name))
            {
                call.StringParameter = currentFsm.GetFsmString(call.StringParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.TextureParameter.Name))
            {
                call.TextureParameter = currentFsm.GetFsmTexture(call.TextureParameter.Name);
            }
            if (!string.IsNullOrEmpty(call.Vector3Parameter.Name))
            {
                call.Vector3Parameter = currentFsm.GetFsmVector3(call.Vector3Parameter.Name);
            }
            return call;
        }

        private static System.Type GetGlobalType(string s)
        {
            System.Type type = System.Type.GetType(s + ",Assembly-CSharp") ?? System.Type.GetType(s + ",PlayMaker");
            if (type == null)
            {
                if (assemblies == null)
                {
                    assemblies = new List<string>();
                    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
                    {
                        assemblies.Add(assembly.FullName);
                    }
                }
                foreach (string str in assemblies)
                {
                    type = System.Type.GetType(s + "," + str);
                    if (type != null)
                    {
                        return type;
                    }
                }
            }
            return type;
        }

        private LayoutOption GetLayoutOption(int paramIndex)
        {
            LayoutOption option = this.layoutOptionParams[this.paramDataPos[paramIndex]];
            if (option == null)
            {
                return new LayoutOption();
            }
            if (!string.IsNullOrEmpty(option.boolParam.Name))
            {
                option.boolParam = currentFsm.GetFsmBool(option.boolParam.Name);
            }
            if (!string.IsNullOrEmpty(option.floatParam.Name))
            {
                option.floatParam = currentFsm.GetFsmFloat(option.floatParam.Name);
            }
            return option;
        }

        private static ParamDataType GetParamDataType(System.Type type)
        {
            if (type == typeof(int))
            {
                return ParamDataType.Integer;
            }
            if (type == typeof(bool))
            {
                return ParamDataType.Boolean;
            }
            if (type == typeof(float))
            {
                return ParamDataType.Float;
            }
            if (type == typeof(string))
            {
                return ParamDataType.String;
            }
            if (type == typeof(Color))
            {
                return ParamDataType.Color;
            }
            if (type == typeof(LayerMask))
            {
                return ParamDataType.LayerMask;
            }
            if (type == typeof(Vector2))
            {
                return ParamDataType.Vector2;
            }
            if (type == typeof(Vector3))
            {
                return ParamDataType.Vector3;
            }
            if (type == typeof(Vector4))
            {
                return ParamDataType.Vector4;
            }
            if (type == typeof(Quaternion))
            {
                return ParamDataType.Quaternion;
            }
            if (type == typeof(Rect))
            {
                return ParamDataType.Rect;
            }
            if (type == typeof(AnimationCurve))
            {
                return ParamDataType.AnimationCurve;
            }
            if (type == typeof(FsmFloat))
            {
                return ParamDataType.FsmFloat;
            }
            if (type == typeof(FsmInt))
            {
                return ParamDataType.FsmInt;
            }
            if (type == typeof(FsmBool))
            {
                return ParamDataType.FsmBool;
            }
            if (type == typeof(FsmString))
            {
                return ParamDataType.FsmString;
            }
            if (type == typeof(FsmGameObject))
            {
                return ParamDataType.FsmGameObject;
            }
            if (type == typeof(FsmOwnerDefault))
            {
                return ParamDataType.FsmOwnerDefault;
            }
            if (type == typeof(FunctionCall))
            {
                return ParamDataType.FunctionCall;
            }
            if (type == typeof(FsmProperty))
            {
                return ParamDataType.FsmProperty;
            }
            if (type == typeof(FsmAnimationCurve))
            {
                return ParamDataType.FsmAnimationCurve;
            }
            if (type == typeof(FsmEvent))
            {
                return ParamDataType.FsmEvent;
            }
            if (type == typeof(GameObject))
            {
                return ParamDataType.GameObject;
            }
            if (type == typeof(FsmVector3))
            {
                return ParamDataType.FsmVector3;
            }
            if (type == typeof(FsmRect))
            {
                return ParamDataType.FsmRect;
            }
            if (type == typeof(FsmQuaternion))
            {
                return ParamDataType.FsmQuaternion;
            }
            if (type == typeof(FsmObject))
            {
                return ParamDataType.FsmObject;
            }
            if (type == typeof(FsmMaterial))
            {
                return ParamDataType.FsmMaterial;
            }
            if (type == typeof(FsmTexture))
            {
                return ParamDataType.FsmTexture;
            }
            if (type == typeof(FsmColor))
            {
                return ParamDataType.FsmColor;
            }
            if (type == typeof(LayoutOption))
            {
                return ParamDataType.LayoutOption;
            }
            if (type == typeof(FsmEventTarget))
            {
                return ParamDataType.FsmEventTarget;
            }
            if (type.IsArray)
            {
                return ParamDataType.Array;
            }
            if (type.IsSubclassOf(typeof(UnityEngine.Object)))
            {
                return ParamDataType.ObjectReference;
            }
            if (type.IsEnum)
            {
                return ParamDataType.Enum;
            }
            return ParamDataType.Unsupported;
        }

        private void LoadActionField(object obj, FieldInfo field, int paramIndex)
        {
            System.Type fieldType = field.FieldType;
            object fsmGameObject = null;
            if (fieldType == typeof(FsmGameObject))
            {
                fsmGameObject = this.GetFsmGameObject(paramIndex);
            }
            else if (fieldType == typeof(FsmEvent))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmEvent(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmFloat))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmFloat(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmInt))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmInt(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmBool))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmBool(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmVector3))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmVector3(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmRect))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmRect(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmQuaternion))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmQuaternion(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmColor))
            {
                fsmGameObject = FsmUtility.ByteArrayToFsmColor(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType == typeof(FsmObject))
            {
                fsmGameObject = this.GetFsmObject(paramIndex);
            }
            else if (fieldType == typeof(FsmMaterial))
            {
                fsmGameObject = this.GetFsmMaterial(paramIndex);
            }
            else if (fieldType == typeof(FsmTexture))
            {
                fsmGameObject = this.GetFsmTexture(paramIndex);
            }
            else if (fieldType == typeof(FunctionCall))
            {
                fsmGameObject = this.GetFunctionCall(paramIndex);
            }
            else if (fieldType == typeof(FsmProperty))
            {
                fsmGameObject = this.GetFsmProperty(paramIndex);
            }
            else if (fieldType == typeof(FsmEventTarget))
            {
                fsmGameObject = this.GetFsmEventTarget(paramIndex);
            }
            else if (fieldType == typeof(LayoutOption))
            {
                fsmGameObject = this.GetLayoutOption(paramIndex);
            }
            else if (fieldType == typeof(FsmOwnerDefault))
            {
                fsmGameObject = this.GetFsmOwnerDefault(paramIndex);
            }
            else if (fieldType == typeof(FsmAnimationCurve))
            {
                fsmGameObject = this.animationCurveParams[this.paramDataPos[paramIndex]] ?? new FsmAnimationCurve();
            }
            else if (fieldType == typeof(FsmString))
            {
                fsmGameObject = this.GetFsmString(paramIndex);
            }
            else if (fieldType == typeof(float))
            {
                fsmGameObject = FsmUtility.BitConverter.ToSingle(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(int))
            {
                fsmGameObject = FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(bool))
            {
                fsmGameObject = FsmUtility.BitConverter.ToBoolean(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(Color))
            {
                fsmGameObject = FsmUtility.ByteArrayToColor(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(Vector2))
            {
                fsmGameObject = FsmUtility.ByteArrayToVector2(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(Vector3))
            {
                fsmGameObject = FsmUtility.ByteArrayToVector3(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(Vector4))
            {
                fsmGameObject = FsmUtility.ByteArrayToVector4(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(Rect))
            {
                fsmGameObject = FsmUtility.ByteArrayToRect(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (fieldType == typeof(string))
            {
                fsmGameObject = FsmUtility.ByteArrayToString(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
            }
            else if (fieldType.IsEnum)
            {
                fsmGameObject = FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]);
            }
            else if (typeof(FsmObject).IsAssignableFrom(fieldType))
            {
                FsmObject obj3 = this.fsmObjectParams[this.paramDataPos[paramIndex]];
                if (obj3 != null)
                {
                    field.SetValue(obj, obj3);
                    return;
                }
            }
            else if (typeof(UnityEngine.Object).IsAssignableFrom(fieldType))
            {
                UnityEngine.Object obj4 = this.unityObjectParams[this.paramDataPos[paramIndex]];
                if (obj4 != null)
                {
                    field.SetValue(obj, obj4);
                    return;
                }
            }
            else
            {
                if (fieldType.IsArray)
                {
                    System.Type globalType = GetGlobalType(this.arrayParamTypes[this.paramDataPos[paramIndex]]);
                    int length = this.arrayParamSizes[this.paramDataPos[paramIndex]];
                    Array array = Array.CreateInstance(globalType, length);
                    for (int i = 0; i < length; i++)
                    {
                        this.nextParamIndex++;
                        this.LoadArrayElement(array, globalType, i, this.nextParamIndex);
                    }
                    field.SetValue(obj, array);
                    return;
                }
                Debug.LogError("ActionData: Missing LoadActionField for type: " + fieldType);
                field.SetValue(obj, null);
                return;
            }
            field.SetValue(obj, fsmGameObject);
        }

        public FsmStateAction[] LoadActions(FsmState state)
        {
            this.byteDataAsArray = this.byteData.ToArray();
            List<FsmStateAction> list = new List<FsmStateAction>();
            resaveActionData = false;
            for (int i = 0; i < this.actionNames.Count; i++)
            {
                FsmStateAction item = this.CreateAction(state, i);
                if (item != null)
                {
                    list.Add(item);
                    item.Init(state);
                }
            }
            if (resaveActionData)
            {
                this.SaveActions(list.ToArray());
                list = new List<FsmStateAction>(this.LoadActions(state));
            }
            return list.ToArray();
        }

        private void LoadArrayElement(Array field, System.Type fieldType, int elementIndex, int paramIndex)
        {
            if ((elementIndex < field.GetLength(0)) && (paramIndex < this.paramDataPos.Count))
            {
                if (fieldType == typeof(FsmGameObject))
                {
                    field.SetValue(this.GetFsmGameObject(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FunctionCall))
                {
                    field.SetValue(this.GetFunctionCall(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmProperty))
                {
                    field.SetValue(this.GetFsmProperty(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(LayoutOption))
                {
                    field.SetValue(this.GetLayoutOption(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmOwnerDefault))
                {
                    field.SetValue(this.GetFsmOwnerDefault(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmAnimationCurve))
                {
                    field.SetValue(this.animationCurveParams[this.paramDataPos[paramIndex]] ?? new FsmAnimationCurve(), elementIndex);
                }
                else if (fieldType == typeof(FsmString))
                {
                    field.SetValue(this.GetFsmString(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmObject))
                {
                    field.SetValue(this.GetFsmObject(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmMaterial))
                {
                    field.SetValue(this.GetFsmMaterial(paramIndex), elementIndex);
                }
                else if (fieldType == typeof(FsmTexture))
                {
                    field.SetValue(this.GetFsmTexture(paramIndex), elementIndex);
                }
                else if (fieldType.IsArray)
                {
                    Debug.LogError("Nested arrays are not supported!");
                }
                else if (fieldType == typeof(FsmEvent))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmEvent(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmFloat))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmFloat(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmInt))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmInt(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmBool))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmBool(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmVector3))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmVector3(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmRect))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmRect(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmQuaternion))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmQuaternion(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(FsmColor))
                {
                    field.SetValue(FsmUtility.ByteArrayToFsmColor(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(float))
                {
                    field.SetValue(FsmUtility.BitConverter.ToSingle(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(int))
                {
                    field.SetValue(FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(bool))
                {
                    field.SetValue(FsmUtility.BitConverter.ToBoolean(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(Color))
                {
                    field.SetValue(FsmUtility.ByteArrayToColor(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(Vector2))
                {
                    field.SetValue(FsmUtility.ByteArrayToVector2(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(Vector3))
                {
                    field.SetValue(FsmUtility.ByteArrayToVector3(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(Vector4))
                {
                    field.SetValue(FsmUtility.ByteArrayToVector4(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(Rect))
                {
                    field.SetValue(FsmUtility.ByteArrayToRect(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (fieldType == typeof(string))
                {
                    field.SetValue(FsmUtility.ByteArrayToString(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]), elementIndex);
                }
                else if (fieldType.IsEnum)
                {
                    field.SetValue(FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]), elementIndex);
                }
                else if (typeof(FsmObject).IsAssignableFrom(fieldType))
                {
                    FsmObject obj2 = this.fsmObjectParams[this.paramDataPos[paramIndex]];
                    if (obj2 != null)
                    {
                        field.SetValue(obj2, elementIndex);
                    }
                }
                else if (typeof(UnityEngine.Object).IsAssignableFrom(fieldType))
                {
                    UnityEngine.Object obj3 = this.unityObjectParams[this.paramDataPos[paramIndex]];
                    if (obj3 != null)
                    {
                        field.SetValue(obj3, elementIndex);
                    }
                }
                else
                {
                    field.SetValue(null, elementIndex);
                }
            }
        }

        private static void LogError(string error)
        {
            if (((currentState != null) && (currentAction != null)) && ((currentFsm != null) && (currentFsm.Owner != null)))
            {
                PlayMakerFSM owner = currentFsm.Owner as PlayMakerFSM;
                ActionReport.LogError(owner, currentState, currentAction, currentActionIndex, error);
            }
        }

        private static void LogInfo(string info)
        {
            if ((currentState != null) && (currentAction != null))
            {
                PlayMakerFSM owner = currentFsm.Owner as PlayMakerFSM;
                ActionReport.Log(owner, currentState, currentAction, currentActionIndex, info, false);
            }
        }

        private void SaveAction(FsmStateAction action)
        {
            if (action != null)
            {
                System.Type actionType = action.GetType();
                this.actionNames.Add(actionType.ToString());
                this.customNames.Add(action.Name);
                this.actionEnabled.Add(action.Enabled);
                this.actionIsOpen.Add(action.IsOpen);
                this.actionStartIndex.Add(this.nextParamIndex);
                this.actionHashCodes.Add(GetActionTypeHashCode(actionType));
                foreach (FieldInfo info in GetFields(actionType))
                {
                    System.Type fieldType = info.FieldType;
                    object obj2 = info.GetValue(action);
                    this.paramName.Add(info.Name);
                    this.SaveActionField(fieldType, obj2);
                    this.nextParamIndex++;
                }
            }
        }

        private void SaveActionField(System.Type fieldType, object obj)
        {
            if (fieldType == typeof(FsmAnimationCurve))
            {
                this.paramDataType.Add(ParamDataType.FsmAnimationCurve);
                this.paramDataPos.Add(this.animationCurveParams.Count);
                this.paramByteDataSize.Add(0);
                this.animationCurveParams.Add((FsmAnimationCurve) obj);
            }
            else if (typeof(UnityEngine.Object).IsAssignableFrom(fieldType))
            {
                this.paramDataType.Add((fieldType == typeof(GameObject)) ? ParamDataType.GameObject : ParamDataType.ObjectReference);
                this.paramDataPos.Add(this.unityObjectParams.Count);
                this.paramByteDataSize.Add(0);
                this.unityObjectParams.Add((UnityEngine.Object) obj);
            }
            else if (fieldType == typeof(FunctionCall))
            {
                this.paramDataType.Add(ParamDataType.FunctionCall);
                this.paramDataPos.Add(this.functionCallParams.Count);
                this.paramByteDataSize.Add(0);
                this.functionCallParams.Add((FunctionCall) obj);
            }
            else if (fieldType == typeof(FsmProperty))
            {
                this.paramDataType.Add(ParamDataType.FsmProperty);
                this.paramDataPos.Add(this.fsmPropertyParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmPropertyParams.Add((FsmProperty) obj);
            }
            else if (fieldType == typeof(FsmEventTarget))
            {
                this.paramDataType.Add(ParamDataType.FsmEventTarget);
                this.paramDataPos.Add(this.fsmEventTargetParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmEventTargetParams.Add((FsmEventTarget) obj);
            }
            else if (fieldType == typeof(LayoutOption))
            {
                this.paramDataType.Add(ParamDataType.LayoutOption);
                this.paramDataPos.Add(this.layoutOptionParams.Count);
                this.paramByteDataSize.Add(0);
                this.layoutOptionParams.Add((LayoutOption) obj);
            }
            else if (fieldType == typeof(FsmGameObject))
            {
                this.paramDataType.Add(ParamDataType.FsmGameObject);
                this.paramDataPos.Add(this.fsmGameObjectParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmGameObjectParams.Add((FsmGameObject) obj);
            }
            else if (fieldType == typeof(FsmOwnerDefault))
            {
                this.paramDataType.Add(ParamDataType.FsmOwnerDefault);
                this.paramDataPos.Add(this.fsmOwnerDefaultParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmOwnerDefaultParams.Add((FsmOwnerDefault) obj);
            }
            else if (fieldType == typeof(FsmString))
            {
                this.paramDataType.Add(ParamDataType.FsmString);
                this.paramDataPos.Add(this.fsmStringParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmStringParams.Add((FsmString) obj);
            }
            else if (fieldType.IsArray)
            {
                System.Type elementType = fieldType.GetElementType();
                if (elementType != null)
                {
                    Array array;
                    if (obj != null)
                    {
                        array = (Array) obj;
                    }
                    else
                    {
                        array = Array.CreateInstance(elementType, 0);
                    }
                    this.paramDataType.Add(ParamDataType.Array);
                    this.paramDataPos.Add(this.arrayParamSizes.Count);
                    this.paramByteDataSize.Add(0);
                    this.arrayParamSizes.Add(array.Length);
                    this.arrayParamTypes.Add(elementType.FullName);
                    foreach (object obj2 in array)
                    {
                        this.nextParamIndex++;
                        this.paramName.Add("");
                        this.SaveActionField(elementType, obj2);
                    }
                }
            }
            else if (fieldType == typeof(float))
            {
                this.paramDataType.Add(ParamDataType.Float);
                this.AddByteData(FsmUtility.BitConverter.GetBytes((float) obj));
            }
            else if (fieldType == typeof(int))
            {
                this.paramDataType.Add(ParamDataType.Integer);
                this.AddByteData(FsmUtility.BitConverter.GetBytes((int) obj));
            }
            else if (fieldType == typeof(bool))
            {
                this.paramDataType.Add(ParamDataType.Boolean);
                this.AddByteData(FsmUtility.BitConverter.GetBytes((bool) obj));
            }
            else if (fieldType == typeof(Color))
            {
                this.paramDataType.Add(ParamDataType.Color);
                this.AddByteData(FsmUtility.ColorToByteArray((Color) obj));
            }
            else if (fieldType == typeof(Vector2))
            {
                this.paramDataType.Add(ParamDataType.Vector2);
                this.AddByteData(FsmUtility.Vector2ToByteArray((Vector2) obj));
            }
            else if (fieldType == typeof(Vector3))
            {
                this.paramDataType.Add(ParamDataType.Vector3);
                this.AddByteData(FsmUtility.Vector3ToByteArray((Vector3) obj));
            }
            else if (fieldType == typeof(Vector4))
            {
                this.paramDataType.Add(ParamDataType.Vector4);
                this.AddByteData(FsmUtility.Vector4ToByteArray((Vector4) obj));
            }
            else if (fieldType == typeof(Rect))
            {
                this.paramDataType.Add(ParamDataType.Rect);
                this.AddByteData(FsmUtility.RectToByteArray((Rect) obj));
            }
            else if (fieldType == typeof(FsmFloat))
            {
                this.paramDataType.Add(ParamDataType.FsmFloat);
                this.AddByteData(FsmUtility.FsmFloatToByteArray((FsmFloat) obj));
            }
            else if (fieldType == typeof(FsmInt))
            {
                this.paramDataType.Add(ParamDataType.FsmInt);
                this.AddByteData(FsmUtility.FsmIntToByteArray((FsmInt) obj));
            }
            else if (fieldType == typeof(FsmBool))
            {
                this.paramDataType.Add(ParamDataType.FsmBool);
                this.AddByteData(FsmUtility.FsmBoolToByteArray((FsmBool) obj));
            }
            else if (fieldType == typeof(FsmVector3))
            {
                this.paramDataType.Add(ParamDataType.FsmVector3);
                this.AddByteData(FsmUtility.FsmVector3ToByteArray((FsmVector3) obj));
            }
            else if (fieldType == typeof(FsmRect))
            {
                this.paramDataType.Add(ParamDataType.FsmRect);
                this.AddByteData(FsmUtility.FsmRectToByteArray((FsmRect) obj));
            }
            else if (fieldType == typeof(FsmQuaternion))
            {
                this.paramDataType.Add(ParamDataType.FsmQuaternion);
                this.AddByteData(FsmUtility.FsmQuaternionToByteArray((FsmQuaternion) obj));
            }
            else if (fieldType == typeof(FsmColor))
            {
                this.paramDataType.Add(ParamDataType.FsmColor);
                this.AddByteData(FsmUtility.FsmColorToByteArray((FsmColor) obj));
            }
            else if (fieldType == typeof(FsmEvent))
            {
                this.paramDataType.Add(ParamDataType.FsmEvent);
                this.AddByteData(FsmUtility.FsmEventToByteArray((FsmEvent) obj));
            }
            else if (fieldType == typeof(string))
            {
                this.paramDataType.Add(ParamDataType.String);
                this.AddByteData(FsmUtility.StringToByteArray((string) obj));
            }
            else if (fieldType == typeof(FsmObject))
            {
                this.paramDataType.Add(ParamDataType.FsmObject);
                this.paramDataPos.Add(this.fsmObjectParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmObjectParams.Add((FsmObject) obj);
            }
            else if (fieldType == typeof(FsmMaterial))
            {
                this.paramDataType.Add(ParamDataType.FsmMaterial);
                this.paramDataPos.Add(this.fsmObjectParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmObjectParams.Add((FsmObject) obj);
            }
            else if (fieldType == typeof(FsmTexture))
            {
                this.paramDataType.Add(ParamDataType.FsmTexture);
                this.paramDataPos.Add(this.fsmObjectParams.Count);
                this.paramByteDataSize.Add(0);
                this.fsmObjectParams.Add((FsmObject) obj);
            }
            else if (fieldType.IsEnum)
            {
                this.paramDataType.Add(ParamDataType.Enum);
                this.AddByteData(FsmUtility.BitConverter.GetBytes((int) obj));
            }
            else if (obj != null)
            {
                Debug.LogError("Save Action: Unsupported parameter type: " + fieldType);
                this.paramDataType.Add(ParamDataType.Unsupported);
                this.paramDataPos.Add(this.byteData.Count);
                this.paramByteDataSize.Add(0);
            }
            else
            {
                this.paramDataType.Add(ParamDataType.Unsupported);
                this.paramDataPos.Add(this.byteData.Count);
                this.paramByteDataSize.Add(0);
            }
        }

        public void SaveActions(FsmStateAction[] actions)
        {
            this.ClearActionData();
            foreach (FsmStateAction action in actions)
            {
                this.SaveAction(action);
            }
        }

        private bool TryConvertArrayElement(Array field, ParamDataType originalParamType, ParamDataType currentParamType, int elementIndex, int paramIndex)
        {
            if (elementIndex >= field.GetLength(0))
            {
                Debug.LogError("Bad array index: " + elementIndex);
                return false;
            }
            if (paramIndex >= this.paramDataPos.Count)
            {
                Debug.LogError("Bad param index: " + paramIndex);
                return false;
            }
            object obj2 = this.ConvertType(originalParamType, currentParamType, paramIndex);
            if (obj2 == null)
            {
                return false;
            }
            field.SetValue(obj2, elementIndex);
            return true;
        }

        private bool TryConvertParameter(FsmStateAction action, FieldInfo field, int paramIndex)
        {
            System.Type fieldType = field.FieldType;
            ParamDataType type2 = this.paramDataType[paramIndex];
            ParamDataType paramDataType = GetParamDataType(fieldType);
            if ((paramDataType != ParamDataType.Array) && (type2 == paramDataType))
            {
                this.LoadActionField(action, field, paramIndex);
            }
            if ((type2 == ParamDataType.String) && (paramDataType == ParamDataType.FsmString))
            {
                LogInfo(field.Name + ": Upgraded from string to FsmString");
                FsmString str = new FsmString();
                str.Value = FsmUtility.ByteArrayToString(this.byteDataAsArray, this.paramDataPos[paramIndex], this.paramByteDataSize[paramIndex]);
                field.SetValue(action, str);
            }
            else if ((type2 == ParamDataType.Integer) && (paramDataType == ParamDataType.FsmInt))
            {
                LogInfo(field.Name + ": Upgraded from int to FsmInt");
                FsmInt num = new FsmInt();
                num.Value = FsmUtility.BitConverter.ToInt32(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, num);
            }
            else if ((type2 == ParamDataType.Float) && (paramDataType == ParamDataType.FsmFloat))
            {
                LogInfo(field.Name + ": Upgraded from float to FsmFloat");
                FsmFloat num2 = new FsmFloat();
                num2.Value = FsmUtility.BitConverter.ToSingle(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, num2);
            }
            else if ((type2 == ParamDataType.Boolean) && (paramDataType == ParamDataType.FsmBool))
            {
                LogInfo(field.Name + ": Upgraded from bool to FsmBool");
                FsmBool @bool = new FsmBool();
                @bool.Value = FsmUtility.BitConverter.ToBoolean(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, @bool);
            }
            else if ((type2 == ParamDataType.GameObject) && (paramDataType == ParamDataType.FsmGameObject))
            {
                LogInfo(field.Name + ": Upgraded from from GameObject to FsmGameObject");
                FsmGameObject obj2 = new FsmGameObject();
                obj2.Value = (GameObject) this.unityObjectParams[this.paramDataPos[paramIndex]];
                field.SetValue(action, obj2);
            }
            else if ((type2 == ParamDataType.GameObject) && (paramDataType == ParamDataType.FsmOwnerDefault))
            {
                LogInfo(field.Name + ": Upgraded from GameObject to FsmOwnerDefault");
                FsmOwnerDefault default3 = new FsmOwnerDefault();
                FsmGameObject obj3 = new FsmGameObject();
                obj3.Value = (GameObject) this.unityObjectParams[this.paramDataPos[paramIndex]];
                default3.GameObject = obj3;
                FsmOwnerDefault default2 = default3;
                field.SetValue(action, default2);
            }
            else if ((type2 == ParamDataType.FsmGameObject) && (paramDataType == ParamDataType.FsmOwnerDefault))
            {
                LogInfo(field.Name + ": Converted from FsmGameObject to FsmOwnerDefault");
                FsmOwnerDefault default5 = new FsmOwnerDefault();
                default5.GameObject = this.fsmGameObjectParams[this.paramDataPos[paramIndex]];
                default5.OwnerOption = OwnerDefaultOption.SpecifyGameObject;
                FsmOwnerDefault default4 = default5;
                field.SetValue(action, default4);
            }
            else if ((type2 == ParamDataType.Vector3) && (paramDataType == ParamDataType.FsmVector3))
            {
                LogInfo(field.Name + ": Upgraded from Vector3 to FsmVector3");
                FsmVector3 vector = new FsmVector3();
                vector.Value = FsmUtility.ByteArrayToVector3(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, vector);
            }
            else if ((type2 == ParamDataType.Rect) && (paramDataType == ParamDataType.FsmRect))
            {
                LogInfo(field.Name + ": Upgraded from Rect to FsmRect");
                FsmRect rect = new FsmRect();
                rect.Value = FsmUtility.ByteArrayToRect(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, rect);
            }
            else if ((type2 == ParamDataType.Quaternion) && (paramDataType == ParamDataType.Quaternion))
            {
                LogInfo(field.Name + ": Upgraded from Quaternion to FsmQuaternion");
                FsmQuaternion quaternion = new FsmQuaternion();
                quaternion.Value = FsmUtility.ByteArrayToQuaternion(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, quaternion);
            }
            else if ((type2 == ParamDataType.Color) && (paramDataType == ParamDataType.FsmColor))
            {
                LogInfo(field.Name + ": Upgraded from Color to FsmColor");
                FsmColor color = new FsmColor();
                color.Value = FsmUtility.ByteArrayToColor(this.byteDataAsArray, this.paramDataPos[paramIndex]);
                field.SetValue(action, color);
            }
            else if ((paramDataType == ParamDataType.FsmMaterial) && (type2 == ParamDataType.ObjectReference))
            {
                LogInfo(field.Name + ": Upgraded from Material to FsmMaterial");
                FsmMaterial material = new FsmMaterial();
                material.Value = this.unityObjectParams[this.paramDataPos[paramIndex]] as Material;
                field.SetValue(action, material);
            }
            else if ((paramDataType == ParamDataType.FsmTexture) && (type2 == ParamDataType.ObjectReference))
            {
                LogInfo(field.Name + ": Upgraded from Texture to FsmTexture");
                FsmTexture texture = new FsmTexture();
                texture.Value = this.unityObjectParams[this.paramDataPos[paramIndex]] as Texture;
                field.SetValue(action, texture);
            }
            else if ((paramDataType == ParamDataType.FsmObject) && (type2 == ParamDataType.ObjectReference))
            {
                LogInfo(field.Name + ": Upgraded from Object to FsmObject");
                FsmObject obj4 = new FsmObject();
                obj4.Value = this.unityObjectParams[this.paramDataPos[paramIndex]];
                field.SetValue(action, obj4);
            }
            else
            {
                if (paramDataType != ParamDataType.Array)
                {
                    return false;
                }
                System.Type globalType = GetGlobalType(this.arrayParamTypes[this.paramDataPos[paramIndex]]);
                System.Type elementType = fieldType.GetElementType();
                if (elementType == null)
                {
                    LogError("Could not make array: " + field.Name);
                    return false;
                }
                int length = this.arrayParamSizes[this.paramDataPos[paramIndex]];
                Array array = Array.CreateInstance(elementType, length);
                if (globalType != elementType)
                {
                    ParamDataType originalParamType = GetParamDataType(globalType);
                    ParamDataType currentParamType = GetParamDataType(elementType);
                    for (int i = 0; i < length; i++)
                    {
                        this.nextParamIndex++;
                        if (!this.TryConvertArrayElement(array, originalParamType, currentParamType, i, this.nextParamIndex))
                        {
                            LogError(string.Concat(new object[] { "Failed to convert Array: ", field.Name, " From: ", originalParamType, " To: ", currentParamType }));
                            return false;
                        }
                        LogInfo(string.Concat(new object[] { field.Name, ": Upgraded Array from ", globalType.FullName, " to ", currentParamType }));
                    }
                }
                else
                {
                    for (int j = 0; j < length; j++)
                    {
                        this.nextParamIndex++;
                        this.LoadArrayElement(array, globalType, j, this.nextParamIndex);
                    }
                }
                field.SetValue(action, array);
            }
            return true;
        }

        private static string TryFixActionName(string actionName)
        {
            if (actionName == "HutongGames.PlayMaker.Actions.ClampFloat")
            {
                return "HutongGames.PlayMaker.Actions.FloatClamp";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.ClampInt")
            {
                return "HutongGames.PlayMaker.Actions.IntClamp";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.AllTrue")
            {
                return "HutongGames.PlayMaker.Actions.BoolAllTrue";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.NoneTrue")
            {
                return "HutongGames.PlayMaker.Actions.BoolNoneTrue";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.AnyTrue")
            {
                return "HutongGames.PlayMaker.Actions.BoolAnyTrue";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.MouseCursor")
            {
                return "HutongGames.PlayMaker.Actions.SetMouseCursor";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.HasChildren")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectHasChildren";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.HasTag")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectCompareTag";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.IsChildOf")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectIsChildOf";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.IsGameObjectNull")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectIsNull";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.IsVisible")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectIsVisible";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.OnGameObjectChange")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectChanged";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.TagSwitch")
            {
                return "HutongGames.PlayMaker.Actions.GameObjectTagSwitch";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.Button")
            {
                return "HutongGames.PlayMaker.Actions.GUIButton";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.HorizontalSlider")
            {
                return "HutongGames.PlayMaker.Actions.GUIHorizontalSlider";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.Label")
            {
                return "HutongGames.PlayMaker.Actions.GUILabel";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.VerticalSlider")
            {
                return "HutongGames.PlayMaker.Actions.GUIVerticalSlider";
            }
            if (actionName == "HutongGames.PlayMaker.Actions.GetGameObjectName")
            {
                return "HutongGames.PlayMaker.Actions.GetName";
            }
            return actionName;
        }

        private FsmStateAction TryRecoverAction(System.Type actionType, FsmStateAction action, int actionIndex)
        {
            UsedIndices.Clear();
            InitFields.Clear();
            int num = this.actionStartIndex[actionIndex];
            int num2 = (actionIndex < (this.actionNames.Count - 1)) ? this.actionStartIndex[actionIndex + 1] : this.paramDataPos.Count;
            if (this.paramName.Count == this.paramDataPos.Count)
            {
                for (int i = num; i < num2; i++)
                {
                    FieldInfo field = this.FindField(actionType, i);
                    if (field != null)
                    {
                        this.nextParamIndex = i;
                        this.LoadActionField(action, field, i);
                        UsedIndices.Add(i);
                        InitFields.Add(field);
                    }
                }
                for (int j = num; j < num2; j++)
                {
                    if (!UsedIndices.Contains(j))
                    {
                        FieldInfo info2 = FindField(actionType, this.paramName[j]);
                        if (info2 != null)
                        {
                            this.nextParamIndex = j;
                            if (this.TryConvertParameter(action, info2, j))
                            {
                                UsedIndices.Add(j);
                                InitFields.Add(info2);
                            }
                        }
                    }
                }
            }
            foreach (FieldInfo info3 in GetFields(actionType))
            {
                if (!InitFields.Contains(info3))
                {
                    LogInfo("New parameter: " + info3.Name + " (set to default value).");
                }
            }
            return action;
        }

        public int ActionCount
        {
            get
            {
                return this.actionNames.Count;
            }
        }
    }
}

